import concurrent.futures  
import threading  
import re,subprocess
import logging
import time
# 共享列表  
mate_list = []  
# 锁  
lock = threading.Lock()  
  

def get_guid(filepath)->str:
    ''' 获取指定文件中的 guid
    '''
    smdStr = f"svn cat \"{filepath}\""
    text = exe_svn_command(smdStr)
    match = re.search(r'guid:\s*(\w+)', text)
    if not match:
        #logging.warning(".meta 文件：%s 解析 GUID 失败", path)
        print(f'.meta 文件：{filepath} 解析 GUID 失败')
        return ''
    return match.group(1)

def exe_svn_command(command):
    try:
        p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
                            shell=True)
        stdout, stderr = p.communicate()
        stdout = stdout.decode("gbk")
        stderr = stderr.decode("gbk")
        if stderr != "":
            print("stderr:\n",stderr)
            logging.warning(stderr)
        return stdout   
    except subprocess.CalledProcessError as e:
        print(f'Subprocess failed with return code {e.returncode}')
    except FileNotFoundError:
        print('Command not found')

#共享列表中添加元素  
def add_to_list(filepath):  
    # 在访问共享列表之前获取锁  
        # 向共享列表中添加元素  
        guid=get_guid(filepath)
        if guid and guid!="":
            with lock:  
                mate_list.append({"path":filepath,"guid":guid})
                # 打印当前线程和列表的长度（仅用于调试）  
                # print(f"Thread {threading.current_thread().name} added {filepath}. List length: {len(mate_list)}")  

def get_project_mates(svn_assets_url,times=1000000)->list:
    ''' 获取项目 mate 文件信息
        svn_assets_url: svn资源根目录(包含/Main/Assets)
    '''
    mate_list = []
    cmdStr = f"svn list -R {svn_assets_url} --non-interactive | find \".meta\" "
    metafile_list = exe_svn_command(cmdStr).splitlines()
    # 去除"~/"
    metafile_list = [item for item in metafile_list if "~/" not in item]
    start_time=time.time()
    # 创建一个ThreadPoolExecutor对象  
    with concurrent.futures.ThreadPoolExecutor(max_workers=6) as executor:  
        futures = [executor.submit(add_to_list, f"{svn_assets_url}/{file}") for file in metafile_list[:times]]
        # 等待所有任务完成  
        concurrent.futures.wait(futures)  
    print(time.time()-start_time)
    return mate_list
print()
get_project_mates("svn://10.11.89.71/SvnToolTest",100)